#!/usr/bin/env python3

import fnmatch
import hashlib
import os
from pathlib import PurePath
import subprocess
import sys

cflags = []
outfile = None
depflags = []
origflags = iter(sys.argv[1:])
try:
    while True:
        flag = next(origflags)
        if flag in ("-MD", "-MMD"):
            depflags.append(flag[:-1])
        elif flag.startswith("-M"):
            depflags.append(flag)
            if flag in ("-MF", "-MT", "-MQ"):
                depflags.append(next(origflags))
        elif flag == "-o":
            outfile = next(origflags)
        else:
            cflags.append(flag)
except StopIteration:
    pass

outflags = ['-o', outfile] if outfile is not None else []

if "-M" in depflags or "-MM" in depflags:
    depflags.extend(flag for flag in cflags if flag not in ('-c', '-S', '-E'))
    result = subprocess.run(['gcc'] + depflags)
    if result.returncode != 0:
        sys.exit(result.returncode)

if '-c' in cflags:
    try:
        rsfile = subprocess.run(
            ['corrode'] + cflags,
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
            check=True
        ).stdout.splitlines()[0]

        if outfile is None:
            outfile = str(PurePath(rsfile).with_suffix(".o"))

        rustwarn = subprocess.run(
            ['rustc', '--crate-type=dylib', '--emit', 'obj', '-o', outfile, rsfile],
            stderr=subprocess.PIPE,
            check=True,
        ).stderr
        if rustwarn:
            sys.stderr.buffer.write(rustwarn)
    except subprocess.SubprocessError as e:
        with open('errors-' + hashlib.md5(e.stderr).hexdigest(), 'wb') as f:
            f.write(e.stderr)

        sys.exit(subprocess.run(['gcc'] + outflags + cflags).returncode)
else:
    sysroot = subprocess.run(
        ['rustc', '--print', 'sysroot'],
        stdout=subprocess.PIPE,
        check=True,
    ).stdout.strip()

    rustlibdir = sysroot + b'/lib/rustlib/x86_64-unknown-linux-gnu/lib/'

    needed = [b'libcompiler-rt.a'] + [
        b'lib' + lib + b'-*.rlib'
        for lib in (b'core', b'std', b'collections', b'panic_unwind', b'rustc_unicode', b'unwind', b'rand', b'alloc', b'alloc_system', b'libc')
    ]
    alllibs = os.listdir(rustlibdir)

    rustlibs = [ rustlibdir + fnmatch.filter(alllibs, pat)[0] for pat in needed ]

    sys.exit(subprocess.run(['gcc'] + outflags + cflags + rustlibs + ['-lgcc_eh', '-pthread', '-lm', '-ldl']).returncode)
